import tkinter as tk
from tkinter import messagebox
import random
import time


class Match3Game:
    """消消乐游戏"""
    
    # 游戏配置
    ROWS = 8
    COLS = 8
    BLOCK_SIZE = 60
    COLORS = [
        "#FF5252",  # 红色 - 1
        "#4CAF50",  # 绿色 - 2
        "#FFEB3B",  # 黄色 - 3
        "#2196F3",  # 蓝色 - 4
        "#9C27B0",  # 紫色 - 5
        "#00BCD4",  # 青色 - 6
        "#FF9800"   # 橙色 - 7
    ]
    
    def __init__(self, root):
        self.root = root
        self.root.title("🎮 消消乐游戏")
        self.root.resizable(False, False)
        
        # 游戏状态
        self.board = [[0] * self.COLS for _ in range(self.ROWS)]
        self.score = 0
        self.selected = None
        self.show_help = False
        self.animating = False
        
        # 创建UI
        self.create_widgets()
        
        # 居中窗口
        self.center_window()
        
        # 初始化游戏
        self.init_game()
    
    def center_window(self):
        """窗口居中"""
        self.root.update_idletasks()
        width = self.root.winfo_width()
        height = self.root.winfo_height()
        x = (self.root.winfo_screenwidth() // 2) - (width // 2)
        y = (self.root.winfo_screenheight() // 2) - (height // 2)
        self.root.geometry(f'{width}x{height}+{x}+{y}')
    
    def create_widgets(self):
        """创建界面组件"""
        # 顶部信息栏
        top_frame = tk.Frame(self.root, bg="#f0f0f0", padx=10, pady=10)
        top_frame.pack(fill=tk.X)
        
        # 分数显示
        score_frame = tk.Frame(top_frame, bg="#f0f0f0")
        score_frame.pack(side=tk.LEFT, padx=10)
        
        tk.Label(
            score_frame,
            text="🏆 分数：",
            font=("Arial", 14, "bold"),
            bg="#f0f0f0"
        ).pack(side=tk.LEFT)
        
        self.score_label = tk.Label(
            score_frame,
            text="0",
            font=("Arial", 14, "bold"),
            fg="#FF5722",
            bg="#f0f0f0"
        )
        self.score_label.pack(side=tk.LEFT)
        
        # 按钮区
        button_frame = tk.Frame(top_frame, bg="#f0f0f0")
        button_frame.pack(side=tk.RIGHT)
        
        tk.Button(
            button_frame,
            text="🔄 重新开始",
            command=self.restart_game,
            font=("Arial", 10, "bold"),
            bg="#4CAF50",
            fg="black",
            padx=10,
            pady=5,
            cursor="hand2"
        ).pack(side=tk.LEFT, padx=5)
        
        self.help_btn = tk.Button(
            button_frame,
            text="❓ 帮助",
            command=self.toggle_help,
            font=("Arial", 10, "bold"),
            bg="#2196F3",
            fg="black",
            padx=10,
            pady=5,
            cursor="hand2"
        )
        self.help_btn.pack(side=tk.LEFT, padx=5)
        
        # 游戏板框架
        game_frame = tk.Frame(self.root, bg="#2c3e50", padx=10, pady=10)
        game_frame.pack()
        
        # 创建Canvas画布
        canvas_width = self.COLS * self.BLOCK_SIZE
        canvas_height = self.ROWS * self.BLOCK_SIZE
        
        self.canvas = tk.Canvas(
            game_frame,
            width=canvas_width,
            height=canvas_height,
            bg="#34495e",
            highlightthickness=0
        )
        self.canvas.pack()
        
        # 绑定鼠标点击事件
        self.canvas.bind("<Button-1>", self.on_click)
        
        # 底部说明栏
        bottom_frame = tk.Frame(self.root, bg="#ecf0f1", padx=10, pady=10)
        bottom_frame.pack(fill=tk.X)
        
        tk.Label(
            bottom_frame,
            text="📖 游戏说明：",
            font=("Arial", 10, "bold"),
            bg="#ecf0f1",
            anchor="w"
        ).pack(anchor="w")
        
        tk.Label(
            bottom_frame,
            text="1. 点击选择一个方块",
            font=("Arial", 9),
            bg="#ecf0f1",
            anchor="w",
            fg="#555"
        ).pack(anchor="w", padx=10)
        
        tk.Label(
            bottom_frame,
            text="2. 点击相邻方块交换位置",
            font=("Arial", 9),
            bg="#ecf0f1",
            anchor="w",
            fg="#555"
        ).pack(anchor="w", padx=10)
        
        # 状态栏
        self.status_label = tk.Label(
            self.root,
            text="准备就绪",
            font=("Arial", 9),
            bg="#34495e",
            fg="white",
            anchor="w",
            padx=10,
            pady=5
        )
        self.status_label.pack(fill=tk.X, side=tk.BOTTOM)
    
    def init_game(self):
        """初始化游戏"""
        # 随机生成棋盘
        for i in range(self.ROWS):
            for j in range(self.COLS):
                self.board[i][j] = random.randint(1, len(self.COLORS))
        
        # 确保初始没有匹配
        while self.check_matches():
            self.remove_matches()
            self.drop_blocks()
            self.fill_board()
        
        self.draw_board()
        self.update_score(0)
        self.status_label.config(text="游戏开始！选择一个方块吧 🎮")
    
    def draw_board(self):
        """绘制游戏板"""
        self.canvas.delete("all")
        
        for i in range(self.ROWS):
            for j in range(self.COLS):
                x1 = j * self.BLOCK_SIZE
                y1 = i * self.BLOCK_SIZE
                x2 = x1 + self.BLOCK_SIZE
                y2 = y1 + self.BLOCK_SIZE
                
                block_value = self.board[i][j]
                color = self.COLORS[block_value - 1]
                
                # 判断是否是选中的方块
                if self.selected and self.selected == (i, j):
                    # 选中状态：加粗边框
                    self.canvas.create_rectangle(
                        x1 + 2, y1 + 2, x2 - 2, y2 - 2,
                        fill=color,
                        outline="#FFD700",
                        width=4
                    )
                else:
                    # 普通状态
                    self.canvas.create_rectangle(
                        x1 + 2, y1 + 2, x2 - 2, y2 - 2,
                        fill=color,
                        outline="#2c3e50",
                        width=2
                    )
                
                # 绘制数字
                self.canvas.create_text(
                    (x1 + x2) / 2,
                    (y1 + y2) / 2,
                    text=str(block_value),
                    font=("Arial", 24, "bold"),
                    fill="white"
                )
    
    def on_click(self, event):
        """处理鼠标点击"""
        if self.animating:
            return
        
        col = event.x // self.BLOCK_SIZE
        row = event.y // self.BLOCK_SIZE
        
        if row < 0 or row >= self.ROWS or col < 0 or col >= self.COLS:
            return
        
        if self.selected is None:
            # 第一次点击：选中方块
            self.selected = (row, col)
            self.draw_board()
            self.status_label.config(text=f"已选中 [{row},{col}]，点击相邻方块进行交换")
        else:
            # 第二次点击：尝试交换
            r1, c1 = self.selected
            r2, c2 = row, col
            
            if self.is_adjacent(r1, c1, r2, c2):
                # 执行交换
                self.swap_blocks(r1, c1, r2, c2)
                self.selected = None
                self.draw_board()
                
                # 检查是否有匹配
                if self.check_matches():
                    self.status_label.config(text="消除中...")
                    self.root.after(300, self.process_matches)
                else:
                    # 无匹配，交换回来
                    self.swap_blocks(r1, c1, r2, c2)
                    self.draw_board()
                    self.status_label.config(text="无法消除，已恢复")
            else:
                # 不相邻，重新选择
                self.selected = (row, col)
                self.draw_board()
                self.status_label.config(text=f"已选中 [{row},{col}]，点击相邻方块进行交换")
    
    def is_adjacent(self, r1, c1, r2, c2):
        """检查两个方块是否相邻"""
        return (abs(r1 - r2) == 1 and c1 == c2) or (abs(c1 - c2) == 1 and r1 == r2)
    
    def swap_blocks(self, r1, c1, r2, c2):
        """交换两个方块"""
        self.board[r1][c1], self.board[r2][c2] = self.board[r2][c2], self.board[r1][c1]
    
    def check_matches(self):
        """检查是否有匹配"""
        # 检查水平匹配
        for i in range(self.ROWS):
            for j in range(self.COLS - 2):
                if (self.board[i][j] != 0 and 
                    self.board[i][j] == self.board[i][j + 1] == self.board[i][j + 2]):
                    return True
        
        # 检查垂直匹配
        for i in range(self.ROWS - 2):
            for j in range(self.COLS):
                if (self.board[i][j] != 0 and 
                    self.board[i][j] == self.board[i + 1][j] == self.board[i + 2][j]):
                    return True
        
        return False
    
    def remove_matches(self):
        """移除匹配的方块"""
        removed = [[False] * self.COLS for _ in range(self.ROWS)]
        match_count = 0
        
        # 标记水平匹配
        for i in range(self.ROWS):
            j = 0
            while j < self.COLS - 2:
                if (self.board[i][j] != 0 and 
                    self.board[i][j] == self.board[i][j + 1] == self.board[i][j + 2]):
                    k = j
                    while k < self.COLS and self.board[i][k] == self.board[i][j]:
                        if not removed[i][k]:
                            removed[i][k] = True
                            match_count += 1
                        k += 1
                    j = k
                else:
                    j += 1
        
        # 标记垂直匹配
        for j in range(self.COLS):
            i = 0
            while i < self.ROWS - 2:
                if (self.board[i][j] != 0 and 
                    self.board[i][j] == self.board[i + 1][j] == self.board[i + 2][j]):
                    k = i
                    while k < self.ROWS and self.board[k][j] == self.board[i][j]:
                        if not removed[k][j]:
                            removed[k][j] = True
                            match_count += 1
                        k += 1
                    i = k
                else:
                    i += 1
        
        # 移除标记的方块
        for i in range(self.ROWS):
            for j in range(self.COLS):
                if removed[i][j]:
                    self.board[i][j] = 0
        
        # 计分
        if match_count >= 3:
            points = (match_count - 2) * 10
            self.update_score(self.score + points)
        
        return match_count > 0
    
    def drop_blocks(self):
        """方块下落"""
        for j in range(self.COLS):
            empty_row = self.ROWS - 1
            for i in range(self.ROWS - 1, -1, -1):
                if self.board[i][j] != 0:
                    if i != empty_row:
                        self.board[empty_row][j] = self.board[i][j]
                        self.board[i][j] = 0
                    empty_row -= 1
    
    def fill_board(self):
        """填充空白"""
        for i in range(self.ROWS):
            for j in range(self.COLS):
                if self.board[i][j] == 0:
                    self.board[i][j] = random.randint(1, len(self.COLORS))
    
    def process_matches(self):
        """处理匹配（含动画）"""
        self.animating = True
        self.remove_matches()
        self.draw_board()
        
        self.root.after(200, self.after_drop)
    
    def after_drop(self):
        """下落后处理"""
        self.drop_blocks()
        self.fill_board()
        self.draw_board()
        
        # 检查是否有新的匹配（连锁）
        if self.check_matches():
            self.status_label.config(text="连锁消除！")
            self.root.after(300, self.process_matches)
        else:
            self.animating = False
            self.status_label.config(text=f"消除完成！当前分数：{self.score} 🎉")
    
    def update_score(self, new_score):
        """更新分数"""
        self.score = new_score
        self.score_label.config(text=str(self.score))
    
    def restart_game(self):
        """重新开始"""
        result = messagebox.askyesno("重新开始", "确定要重新开始游戏吗？")
        if result:
            self.score = 0
            self.selected = None
            self.init_game()
    
    def toggle_help(self):
        """显示/隐藏帮助"""
        help_text = """
🎮 消消乐游戏帮助

🎯 游戏目标：
   通过交换相邻方块，使3个或更多
   相同颜色的方块连成一线来消除它们

🎮 游戏规则：
   1. 点击选择第一个方块
   2. 再点击相邻方块进行交换
   3. 只能与上下左右相邻的方块交换
   4. 形成3个或以上连线即可消除
   5. 消除后上方方块下落，顶部填充

🏆 计分规则：
   消除3个方块: +10分
   消除4个方块: +20分
   消除5个方块: +30分
   (以此类推，每多一个+10分)

💡 提示：
   - 方块用不同颜色和数字1-7标识
   - 选中的方块会显示金色边框
   - 支持连锁消除获得更多分数
   - 点击"重新开始"可以开始新游戏

祝你游戏愉快！🎉
        """
        messagebox.showinfo("游戏帮助", help_text)


def main():
    """主函数"""
    root = tk.Tk()
    game = Match3Game(root)
    root.mainloop()


if __name__ == "__main__":
    main()
